package cnsatmsmart.automation.mmi.model.data.TSafe;

import java.util.Collection;
import java.util.Iterator;

import cnsatmsmart.automation.mmi.helper.utilities.TSafe.GlobalEnvVars;

/**
 * @author SIK - PTIK, BPPT
 **/

public class Flight {   //based on TSafe
    /* const */
        private static final long MIN_UPDATE_PERIOD = 30000l;
            //nilai default untuk perioda update minimum

        public static final String HAS_PLAN = "HAS FLIGHT PLAN";
        public static final String NO_PLAN = "NO FLIGHT PLAN";
        public static final String BLUNDERING = "BLUNDERING";
        public static final String CONFORMING = "CONFORMING";
        public static final String CONFLICTING = "CONFLICTING";
        public static final String NO_CONFLICTING = "NO CONFLICTING";

        public static int STATUS_OK = 0;
        public static int STATUS_SL = 2;
        public static int STATUS_PL = 5;
        public static int STATUS_RM = 7;

    /* atribut - atribut yang dimiliki oleh kelas Flight */
        private String aircraftFlightID;
        private String aircraftUniqueID;

        private FlightTrack track;
        private FlightTrack rtracker;
        private FlightPlan plan;
        
        private String country;
        
        private long lastUpdate;
        
        private boolean selected;

        private boolean blundering;
        private String blunderInfo;
        private boolean conflicting;
        private Collection conflictInfo;

    /* constructor - user defined ctor, no default ctor */
        // <editor-fold defaultstate="collapsed" desc="ctor">
        /*
         * @param = atribut
         */
        public Flight (String aircraftFlightID, String aircraftUniqueID, FlightTrack track, String country, long lastUpdate, boolean selected) {
            this(aircraftFlightID, aircraftUniqueID, track, null, country, lastUpdate, selected);
        }
        public Flight (String aircraftFlightID, String aircraftUniqueID, FlightPlan plan, String country, long lastUpdate, boolean selected) {
            this(aircraftFlightID, aircraftUniqueID, null, plan, country, lastUpdate, selected);
        }
        public Flight (String aircraftFlightID, String aircraftUniqueID, FlightTrack track, FlightPlan plan, String country, long lastUpdate, boolean selected) {
            if ((aircraftFlightID == null) && (this.aircraftFlightID == null)) {
                throw  new NullPointerException("null aircraftFlightID");
            }
            if (aircraftUniqueID == null) {
                throw  new NullPointerException("null aircraftUniqueID");
            }
            if (this.aircraftFlightID == null) {
                this.aircraftFlightID = aircraftFlightID;
            }
            this.aircraftUniqueID = aircraftUniqueID;
            this.track = track;
            this.plan = plan;
            this.country = country;
            if (track != null) {
                if (lastUpdate == 0l) {
                    this.lastUpdate = System.currentTimeMillis();
                } else {
                    this.lastUpdate = lastUpdate;
                }
            } else {
                this.lastUpdate = 0l;
            }
            this.selected = selected;
            this.blundering = false;
            this.blunderInfo = null;
            this.conflicting = false;
            this.conflictInfo = null;
        }
        public Flight (Flight f, boolean copyTrack) {
            this.aircraftFlightID = f.getAirCraftFlightID();
            this.aircraftUniqueID = f.getAirCraftUniqueID();
            this.track = (copyTrack ? new FlightTrack(f.getFlightTrack()) : f.getFlightTrack());
            this.plan = f.getFlightPlan();
            this.country = f.getCountry();
            this.lastUpdate = f.getLastUpdate();
            this.selected = f.getSelected();
            this.blundering = false;
            this.blunderInfo = null;
            this.conflicting = false;
            this.conflictInfo = null;
        }
        public Flight (Flight f) {
            this(f, false);
        }
        // </editor-fold>

    /* setter */
        public void setAirCraftFlightID (String aircraftFlightID) {
            /* I.S. sebarang */
            /* F.S. this.aircraftFlightID terdefinisi dan bernilai sama dengan parameter aircraftFlightID */
            /* Proses : mengisikan dan mengubah nilai this.aircraftFlightID dengan parameter aircraftFlightID */
                this.aircraftFlightID = aircraftFlightID;
        }
        public void setAirCraftUniqueID (String aircraftUniqueID) {
            /* I.S. sebarang */
            /* F.S. this.aircraftUniqueID terdefinisi dan bernilai sama dengan parameter aircraftUniqueID */
            /* Proses : mengisikan dan mengubah nilai this.aircraftUniqueID dengan parameter aircraftUniqueID */
                this.aircraftUniqueID = aircraftUniqueID;
        }
        public void setFlightTrack (FlightTrack track) {
            /* I.S. sebarang */
            /* F.S. this.track terdefinisi dan bernilai sama dengan parameter track */
            /* Proses : mengisikan dan mengubah nilai this.track dengan parameter track */
                this.lastUpdate = System.currentTimeMillis();
                this.track = track;
        }
        public void setRouteTracker (FlightTrack rtracker) {
            /* I.S. sebarang */
            /* F.S. this.rtracker terdefinisi dan bernilai sama dengan parameter rtracker */
            /* Proses : mengisikan dan mengubah nilai this.rtracker dengan parameter rtracker */
                this.rtracker = rtracker;
        }
        public void setFlightPlan (FlightPlan plan) {
            /* I.S. sebarang */
            /* F.S. this.plan terdefinisi dan bernilai sama dengan parameter plan */
            /* Proses : mengisikan dan mengubah nilai this.plan dengan parameter plan */
                this.plan = plan;
        }
        public void setBlunderInfo (boolean blunder, String blunderInfo) {
            /* I.S. sebarang */
            /* F.S. this.blundering terdefinisi dan bernilai sama dengan parameter blunder
                    this.blunderInfo terdefinisi dan bernilai sama dengan parameter blunderInfo */
            /* Proses : mengisikan dan mengubah nilai this.blundering dengan parameter blunder
                        mengisikan dan mengubah nilai this.blunderInfo dengan parameter blunderInfo */
                this.blundering = blunder;
                this.blunderInfo = blunderInfo;
        }
        public void setConflictInfo (boolean conflict, Collection conflictInfo) {
            /* I.S. sebarang */
            /* F.S. this.conflicting terdefinisi dan bernilai sama dengan parameter conflict
                    this.conflictInfo terdefinisi dan bernilai sama dengan parameter conflictInfo */
            /* Proses : mengisikan dan mengubah nilai this.conflicting dengan parameter conflict
                        mengisikan dan mengubah nilai this.conflictInfo dengan parameter conflictInfo */
                this.conflicting = conflict;
                this.conflictInfo = conflictInfo;
        }

    /* getter */
        public String getAirCraftFlightID () {
            /* mengembalikan nilai dari atribut aircraftFlightID */
            return (this.aircraftFlightID);
        }
        public String getAirCraftUniqueID () {
            /* mengembalikan nilai dari atribut aircraftUniqueID */
            return (this.aircraftUniqueID);
        }
        public FlightTrack getFlightTrack () {
            /* mengembalikan nilai dari atribut track */
            return (this.track);
        }
        public FlightTrack getRouteTracker () {
            /* mengembalikan nilai dari atribut rtracker */
            return (this.rtracker);
        }
        public FlightPlan getFlightPlan () {
            /* mengembalikan nilai dari atribut plan */
            return (this.plan);
        }
        public String getCountry () {
            /* mengembalikan nilai dari atribut country */
            return (this.country);
        }
        public long getLastUpdate () {
            /* mengembalikan nilai dari atribut lastUpdate */
            return (this.lastUpdate);
        }
        public boolean getSelected () {
            /* mengembalikan nilai dari atribut selected */
            return (this.selected);
        }
        public String getBlunderInfo () {
            /* mengembalikan nilai dari atribut blunderInfo */
            return (this.blunderInfo);
        }
        public String getConflictInfo () {
            /* mengembalikan nilai dari atribut conflictInfo */
            if (this.conflictInfo == null) {
                return (null);
            }

            StringBuilder strBuildr = new StringBuilder();
            for (Iterator iter = this.conflictInfo.iterator(); iter.hasNext(); strBuildr.append(" ")) {
                FlightConflict fc = (FlightConflict)iter.next();
                Flight f = fc.getFlight2();
                strBuildr.append(f.getAirCraftFlightID());
            }
            strBuildr.deleteCharAt(strBuildr.length() - 1);
        
            return (strBuildr.toString());
        }

    /* method - method yang dimiliki oleh kelas Flight */
        public boolean isUpdated (long currentTime) {
            if (currentTime == 0l) {
                currentTime = System.currentTimeMillis();
            }
            if (this.lastUpdate == 0l) {
                this.lastUpdate = currentTime;
            }

            return ((currentTime - this.lastUpdate) < 30000l);
        }
        public boolean isBlundering () {
            return (this.blundering);
        }
        public boolean isConflicting () {
            return (this.conflicting);
        }
        public int getStatus () {
            long currentTime = System.currentTimeMillis();
            if ((currentTime - this.lastUpdate) >= (long)STATUS_RM * GlobalEnvVars.LONG_MINUTE) {
                return (STATUS_RM);
            }
            if ((currentTime - this.lastUpdate) >= (long)STATUS_PL * GlobalEnvVars.LONG_MINUTE) {
                return (STATUS_PL);
            }
            if ((currentTime - this.lastUpdate) >= (long)STATUS_SL * GlobalEnvVars.LONG_MINUTE) {
                return (STATUS_SL);
            }
            return (STATUS_OK);
        }

    @Override
    public String toString () {
        return (this.aircraftFlightID);
    }
    @Override
    public int hashCode () {
        return (this.aircraftUniqueID.hashCode());
    }
    @Override
    public boolean equals (Object o) {
        return ((o != null) && (o instanceof Flight) && (((Flight)o).getAirCraftUniqueID().equals(this.aircraftUniqueID)));
    }
}
